home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / demobook / icons.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  31.6 KB  |  1,133 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include "exinterfmotif.h"
  19. #include <gl.h>
  20. #include <string.h>
  21. #include <gl/image.h>
  22. #include <unistd.h>
  23. #include "exbookglo.h"
  24. #include "exglobals.h"
  25. #include "exinterf.h"
  26.  
  27. extern struct indexlist *add_keyword();
  28. extern struct indexlist *find_keyword();
  29. extern struct grptmpltstruct *find_group_wi_name();
  30. extern unsigned long *readicon_i();
  31. void remove_file(struct filestruct *deadfile);
  32. struct filestruct *add_file(char *newfile);
  33. void do_iconfiles(struct icntmpltstruct *icnptr);
  34. void print_files();
  35. void print_icon_files(struct icntmpltstruct *icn);
  36.  
  37. char inbuf[70];
  38.  
  39. /************************************************************
  40. *
  41. * count the polygons in an icon so that storage can be
  42. * allocated all at once.
  43. *
  44. ************************************************************/
  45. int countpolys(FILE *iconfp)
  46. {
  47.    int bufndx;
  48.    int polycount;
  49.    char tmp[20];
  50.    int len;
  51.  
  52.      /* count the number of polygons */
  53.    polycount = 0;
  54.    while ( fgets(inbuf,60,iconfp) != NULL)
  55.       {
  56. /* find the first char that is not a tab */
  57.       bufndx = 0;
  58.       len = strlen(inbuf);
  59.       while (bufndx < len+1 && inbuf[bufndx] == '\t')
  60.          bufndx++;
  61.       if (inbuf[bufndx] == 'b')
  62.          {
  63.          polycount++;
  64. /*
  65.          strncpy(tmp, &(inbuf[bufndx]), 10);
  66.          if (strncmp(tmp, "bgnoutlinepolygon", 10) == 0)
  67.             polycount++;
  68. */
  69.          }
  70.       }
  71.    rewind(iconfp);
  72.    return(polycount);
  73. }
  74.  
  75. /************************************************************
  76. *
  77. * Print out information about the icons.  For debugging.
  78. * DO NOT comment out the  print statements, look for 
  79. * calls to print_icons in the rest of the code.
  80. *
  81. ************************************************************/
  82. print_icons()
  83. {
  84.    struct icntmpltstruct *tmpicn;
  85.    struct indexlist *kwrd;
  86.    struct wordlist *wrdptr;
  87.    struct filelist *adfptr;
  88.    struct grpliststruct *glist;
  89.    int i;
  90.  
  91.    tmpicn = firsticon;
  92.    while (tmpicn != NULL)
  93.    {
  94.    printf(" Icon Name : %s \n",tmpicn->nameptr->string);
  95. /*
  96.    printf("startstring %s\n",tmpicn->startstring);
  97.    if (tmpicn->geofile != NULL)
  98.       printf("filename %s\n",tmpicn->geofile->name);
  99.    if (tmpicn->imgfile != NULL)
  100.       printf("filename %s\n",tmpicn->imgfile->name);
  101.    adfptr = tmpicn->addtlfiles;
  102.    while ( adfptr!= NULL)
  103.       {
  104.       if (adfptr->file != NULL)
  105.         printf(" file %s  \n",adfptr->file->name);
  106.       adfptr = adfptr->next;
  107.       }
  108. */
  109.    printf("     occurs %d  num key %d \n",tmpicn->occurences, tmpicn->numkey);
  110.    if (tmpicn->numkey != 0)
  111.       {
  112.       wrdptr = tmpicn->keywords;
  113.       printf("    keywords: \n");
  114.       for (i = 0; i < tmpicn->numkey; i++)
  115.          {
  116.          kwrd = wrdptr->indexptr;
  117.          printf("        %s  %d \n",kwrd->string, kwrd->num);
  118.          wrdptr = wrdptr->next;
  119.          }
  120.       }
  121.    if (tmpicn->grps != NULL)
  122.       {
  123.       glist = tmpicn->grps;
  124.       printf("    groups: \n");
  125.       while (glist != NULL)
  126.          {
  127.          printf("         %s  \n", glist->grpptr->nameptr->string);
  128.          glist = glist->next;
  129.          }
  130.       }
  131.    tmpicn = tmpicn->nexticntmplt;
  132.    }
  133. }
  134.  
  135. /************************************************************
  136. *
  137. * Delete an icon.  If this is the last icon on a page, delete
  138. * that page, too.  If that page was the last one in a
  139. * group, delete that group.
  140.  
  141. Currently, If a demo is in the alphabetical group and
  142. nowhere else, it can be deleted.  This porogram can not
  143. go through the other groups and remove references to an
  144. iconbefore deleting it.  But I think that this will be
  145. possible sometime.
  146. *
  147. ************************************************************/
  148. void deleteicon(thisgroup, iconnum, side)
  149. struct grptmpltstruct *thisgroup;
  150. int iconnum, side;
  151. {
  152.    int i;
  153.    struct icntmpltstruct *dead_icon_ptr, *tmpicn, *previcn;
  154.    struct wordlist *wrdptr, *nextwrd;
  155.    struct grpliststruct *glistptr, *prevglist;
  156.    Boolean found, backdone;
  157.    struct iconstruct *thisiconptr;
  158.    struct iconstruct *tmpiconptr, *previconptr, *iconhead, *grpiconptr;
  159.    struct pagestruct *thispage, *tmppg;
  160.    float org[3], rot[3], ang;
  161.    struct filelist *tmpfptr;
  162.    Boolean redraw;
  163.  
  164.    redraw = FALSE;
  165.    previconptr = NULL;
  166.    if (side == 1)
  167.       {
  168.       thispage = rightpage;
  169.       thisiconptr = thispage->fronticons;
  170.       }
  171.    else 
  172.       {
  173.       thispage = leftpage;
  174.       thisiconptr = thispage->backicons;
  175.       }
  176.    if (iconnum == 0)
  177.       {
  178.       if (side == 1)
  179.          {
  180.          tmppg = thispage->prevpage;
  181.          if (tmppg != NULL)
  182.             {
  183.             previconptr = tmppg->backicons;
  184.             redraw = TRUE;
  185.             }
  186.          }
  187.       else
  188.          previconptr = thispage->fronticons;
  189.       if (previconptr != NULL)
  190.          {
  191.          while (previconptr->nexticon != thisiconptr)
  192.             {
  193.             previconptr = previconptr->nexticon;
  194.             }
  195.          }
  196.       }
  197.    i = 0;
  198.    while (i != iconnum || (!thisiconptr->ok && Hide))
  199.       {
  200.       if (!Hide || thisiconptr->ok)
  201.          i++;
  202.       previconptr = thisiconptr;
  203.       thisiconptr = thisiconptr->nexticon;
  204.       }
  205.  
  206.    DialogType = 2;
  207.    sprintf(msgstring,"%s",thisiconptr->iconptr->nameptr->string);
  208.    popup_Question();
  209.    handleMessageEvents();
  210.    if(DeleteDemoFlag != TRUE)
  211.      return;
  212.  
  213.  
  214.    if (thisgroup->nameptr == find_keyword("Master Index") )
  215.       {
  216.         /* take it out of the book completely */
  217.       if (thisiconptr->iconptr->occurences == 1)
  218.          {
  219. /* go through the master list of icons and remove this icon from the book */
  220.          if (numberoficons == 1)
  221.             {
  222.             free(firsticon->startstring);
  223.             free(firsticon);
  224.             firsticon = NULL;
  225.             lasticon = NULL;
  226.             curicon = NULL;
  227.             free(firstgroup);
  228.             firstgroup = NULL;
  229.             lastgroup = NULL;
  230.             curgroup = NULL;
  231.             leftpage = NULL;
  232.             rightpage = NULL;
  233.             OPENBOOK = FALSE;
  234.             resetshelfcolors();
  235.             numberofgroups = 0;
  236.             numberofbooks = 0;
  237.             numberoficons = 0;
  238.             currentbook = -1;
  239.             selected = -1;
  240.             prevselection = -1;
  241.             headfile = NULL;  /* ERROR  is there anything here? */
  242.             Index = NULL;
  243.             drawscene(0);
  244.             }
  245.          else  
  246.             {
  247.             tmpicn = firsticon;
  248.             if (thisiconptr->iconptr == firsticon)
  249.                {
  250.                firsticon = thisiconptr->iconptr->nexticntmplt;
  251.                }
  252.             else
  253.                {
  254.                while (tmpicn != NULL && tmpicn != thisiconptr->iconptr)
  255.                   {
  256.                   previcn = tmpicn;
  257.                   tmpicn = tmpicn->nexticntmplt;
  258.                   }
  259.                previcn->nexticntmplt = tmpicn->nexticntmplt;
  260.                }
  261.             selected = -1;
  262.             numberoficons--;
  263.             dead_icon_ptr = tmpicn;
  264.             dead_icon_ptr->nameptr->icon = NULL;
  265.             remove_keyword(dead_icon_ptr->nameptr);
  266.             delete_keywords( dead_icon_ptr, 0);
  267.             remove_file(dead_icon_ptr->geofile);
  268.             remove_file(dead_icon_ptr->imgfile);
  269.             remove_file(dead_icon_ptr->helpfile);
  270.             tmpfptr = dead_icon_ptr->addtlfiles;
  271.             while  (tmpfptr != NULL)
  272.                {
  273.                remove_file(tmpfptr->file);
  274.                tmpfptr->file = NULL;
  275.                tmpfptr = tmpfptr->next;
  276.                }
  277.             group_setup(firsticon, 0, thisgroup);
  278.             }
  279.          }
  280.       else  /* this demo occurs in other groups in the library */
  281.          {
  282.       sprintf(msgstring, "Because this is an early version of the\ndemobook, demos will not be removed\nfrom the main book while they are\nmembers of other books.");
  283.       popup_Message();
  284.          }
  285.       }
  286.    else  /* not the alphabetical group */
  287.       {
  288.       (thisiconptr->iconptr->occurences) -= 1;
  289.       selected = -1;
  290.       seliconptr = NULL;
  291.  
  292.       dead_icon_ptr = thisiconptr->iconptr;
  293.  
  294.       /* take reference to this group out of the icon's list of groups */
  295.       glistptr = dead_icon_ptr->grps;
  296.       prevglist = NULL;
  297.       while (glistptr != NULL && glistptr->grpptr != thisgroup)
  298.          {
  299.          prevglist = glistptr;
  300.          glistptr = glistptr->next;
  301.          }
  302.       if (glistptr != NULL)
  303.          {
  304.             if (glistptr == dead_icon_ptr->grps)
  305.                dead_icon_ptr->grps = dead_icon_ptr->grps->next;
  306.             else if (glistptr->next == NULL)
  307.                {
  308.                if (prevglist != NULL)
  309.                   prevglist->next = NULL;
  310.                }
  311.             else
  312.                {
  313.                prevglist->next = glistptr->next;
  314.                }
  315.             free(glistptr);
  316.             glistptr = NULL;
  317.          }
  318.  
  319. /*
  320.       previconptr = thisiconptr;
  321.       thisiconptr = thisiconptr->nexticon;
  322. */
  323.       if (thispage != NULL)
  324.          {
  325.          if (thispage->prevpage == NULL && thispage->nextpage == NULL && thispage->frontnumicons + thispage->backnumicons == 1)
  326.             {
  327.             deletegroup(curgroup);
  328.             curgroup = NULL;
  329.             currentbook = -1;
  330.             OPENBOOK = FALSE;
  331.             drawscene(0);
  332.             }
  333.          else
  334.             {
  335.             if (previconptr == NULL) /* only if this is first icon in book */
  336.                {
  337.                if (side == 1)
  338.                   thispage->fronticons = thisiconptr->nexticon;
  339.                else
  340.                   thispage->backicons = thisiconptr->nexticon;
  341.                }
  342.             else 
  343.                previconptr->nexticon = thisiconptr->nexticon;
  344.             group_setup(NULL, NULL, thisgroup);
  345.             tmppg = thisgroup->firstpage;
  346.             if (side == 1)  /* front & right */
  347.                {
  348.                while (tmppg != NULL && tmppg != rightpage)
  349.                   tmppg = tmppg->nextpage;
  350.                if (tmppg == NULL)
  351.                   {
  352.                   leftpage = thisgroup->lastpage;
  353.                   rightpage = NULL;
  354.                   }
  355.                else
  356.                   {
  357.                   rightpage = tmppg;
  358.                   leftpage = rightpage->prevpage;
  359.                   }
  360.                }
  361.             else
  362.                {
  363.                while (tmppg != NULL && tmppg != leftpage)
  364.                   tmppg = tmppg->nextpage;
  365.                if (tmppg == NULL)
  366.                   {
  367.                   rightpage = thisgroup->firstpage;
  368.                   leftpage = NULL;
  369.                   }
  370.                else
  371.                   {
  372.                   if (tmppg->backnumicons > 0)
  373.                      {
  374.                      leftpage = tmppg;
  375.                      rightpage = leftpage->nextpage;
  376.                      }
  377.                   else
  378.                      {
  379.                      rightpage = tmppg;
  380.                      leftpage = rightpage->prevpage;
  381.                      }
  382.                   }
  383.                }
  384.             }
  385.          }
  386.       }
  387.  
  388. /*ERROR to delete a demo from the book, need to take it out of all other groups
  389.     can remove it if it's not present in any other groups
  390. */
  391.    if (redraw)
  392.       drawscene(0);
  393.    if (Indexwin >= 0)
  394.       update_index_win();
  395. }
  396.  
  397. /************************************************************
  398. *
  399. * Given a string, allocate the storage and make it the
  400. * startstring for a demo.
  401. *
  402. ************************************************************/
  403. void set_start_string(iptr,s)
  404. struct icntmpltstruct *iptr;
  405. char *s;
  406. {
  407.    if (strlen(s) > 0)
  408.       {
  409.       iptr->startstring = (char *)malloc(strlen(s)+1);
  410.       iptr->startstring = strcpy(iptr->startstring, s);
  411.       }
  412.    else
  413.       iptr->startstring = NULL;
  414. }
  415.  
  416. void set_alt_command(iptr,s)
  417. struct icntmpltstruct *iptr;
  418. char *s;
  419. {
  420.    if (strlen(s) > 0)
  421.       {
  422.       iptr->alt_command = (char *)malloc(strlen(s)+1);
  423.       iptr->alt_command = strcpy(iptr->alt_command, s);
  424.       }
  425.    else
  426.       iptr->alt_command = NULL;
  427. }
  428.  
  429. fix_icon_ok(struct icntmpltstruct *icnptr)
  430. {
  431.    struct grpliststruct *grplstptr;
  432.    struct iconstruct *iconptr;
  433.    struct grptmpltstruct *grpptr;
  434.    Boolean done;
  435.    
  436.    grplstptr = icnptr->grps;
  437.    while (grplstptr != NULL)
  438.       {
  439.       grpptr = grplstptr->grpptr;
  440.       if (grpptr != NULL)
  441.          {
  442.          iconptr = grpptr->firstpage->fronticons;
  443.          done = FALSE;
  444.          while(!done && iconptr != NULL)
  445.             {
  446.             if (iconptr->iconptr == icnptr)
  447.                {
  448.                iconptr->ok = icnptr->ok;
  449.                done = TRUE;
  450.                }
  451.             iconptr = iconptr->nexticon;
  452.             }
  453.          }
  454.       grplstptr = grplstptr->next;
  455.       }
  456. }
  457.  
  458. savedemochanges()
  459. {
  460.    struct icntmpltstruct *icnptr;
  461.    struct indexlist *tmpptr;
  462.    struct charlist *charptr, *prevcharptr;
  463.    struct wordlist *wrdptr, *twrd;
  464.    int i;
  465.    Boolean newfile;
  466.    FILE *iconfp;
  467.    struct filelist *tmpfptr, *prevfptr;
  468.    struct filestruct *tmpfs;
  469.    Boolean indexchange;
  470.    struct grpliststruct *grplstptr;
  471.  
  472.    indexchange = FALSE;
  473.    selected = -1;
  474.    icnptr = curicon;
  475.    if (strcmp(icnptr->nameptr->string, ADName.buf) != 0 )
  476.       {
  477.       indexchange = TRUE;
  478.       tmpptr = icnptr->nameptr;
  479.       if (tmpptr != NULL)
  480.          tmpptr->icon = NULL;
  481.       remove_keyword(tmpptr);
  482.       if (ADName.bufpos == 0)
  483.          if (HeadChar != NULL)
  484.             icnptr->nameptr = add_keyword(HeadChar->str);
  485.          else
  486.             icnptr->nameptr = add_keyword("unknown");
  487.       else
  488.          icnptr->nameptr = add_keyword(ADName.buf);
  489.       tmpptr = icnptr->nameptr;
  490.       if (tmpptr != NULL)
  491.          tmpptr->icon = icnptr;
  492.       alphabetize();
  493.       group_setup(firsticon, NULL, find_group_wi_name("Master Index") );
  494.       }
  495.  
  496.    if (strcmp(icnptr->startstring, ADCommand.buf) != 0 )
  497.       {
  498.       free(icnptr->startstring);
  499.       set_start_string(icnptr, ADCommand.buf);
  500.       }
  501.  
  502.    if (icnptr->alt_command != NULL && strcmp(icnptr->alt_command, ADAltCommand.buf) != 0 )
  503.       {
  504.       free(icnptr->alt_command);
  505.       set_alt_command(icnptr, ADAltCommand.buf);
  506.       }
  507.    else if (icnptr->alt_command == NULL)
  508.       set_alt_command(icnptr, ADAltCommand.buf);
  509.  
  510.    if (icnptr->helpfile == NULL && ADHfile.bufpos != 0)
  511.       icnptr->helpfile = add_file(ADHfile.buf);
  512.    else if (icnptr->helpfile != NULL && strcmp(icnptr->helpfile->name, ADHfile.buf) != 0 )
  513.       {
  514.       tmpfs = icnptr->helpfile;
  515.       remove_file(tmpfs);
  516.       if (ADHfile.bufpos == 0)
  517.          icnptr->helpfile = NULL;
  518.       else
  519.          icnptr->helpfile = add_file(ADHfile.buf);
  520.       }
  521.  
  522.    newfile = 0;
  523.    if (icnptr->geofile == NULL && ADIfile.bufpos != 0)
  524.       {
  525.       icnptr->geofile = add_file(ADIfile.buf);
  526.       newfile = 1;
  527.       }
  528.    else if (icnptr->geofile != NULL && strcmp(icnptr->geofile->name, ADIfile.buf) != 0 )
  529.       {
  530.       tmpfs = icnptr->geofile;
  531.       remove_file(tmpfs);
  532.       if (ADIfile.bufpos == 0)
  533.          icnptr->geofile = NULL;
  534.       else
  535.          icnptr->geofile = add_file(ADIfile.buf);
  536.       newfile = 1;
  537.       }
  538.  
  539.    if (icnptr->imgfile == NULL && ADIfile2.bufpos != 0)
  540.       {
  541.       icnptr->imgfile = add_file(ADIfile2.buf);
  542.       newfile = 1;
  543.       }
  544.    else if (icnptr->imgfile != NULL && strcmp(icnptr->imgfile->name, ADIfile2.buf) != 0 )
  545.       {
  546.       tmpfs = icnptr->imgfile;
  547.       remove_file(tmpfs);
  548.       if (ADIfile2.bufpos == 0)
  549.          icnptr->imgfile = NULL;
  550.       else
  551.          icnptr->imgfile = add_file(ADIfile2.buf);
  552.       newfile = 1;
  553.       }
  554.  
  555.    if (newfile)
  556.       do_iconfiles(icnptr);
  557.  
  558.    if (KW_change)
  559.       {
  560.       indexchange = TRUE;
  561.       wrdptr = icnptr->keywords;
  562.       while (wrdptr != NULL)
  563.          {
  564.          remove_keyword_icon(wrdptr->indexptr, icnptr);
  565.          twrd = wrdptr;
  566.          wrdptr = wrdptr->next;
  567.          free(twrd);
  568.          }
  569.       icnptr->keywords = NULL;
  570.       charptr = HeadChar;
  571.       i = 0;
  572.       while (charptr != NULL)
  573.          {
  574.          if (icnptr->keywords == NULL)
  575.             {
  576.           icnptr->keywords=(struct wordlist *)malloc(sizeof(struct wordlist));
  577.             wrdptr = icnptr->keywords;
  578.             }
  579.          else
  580.             {
  581.             wrdptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  582.             wrdptr = wrdptr->next;
  583.             }
  584.          i++;
  585.          wrdptr->next = NULL;
  586.          wrdptr->indexptr = add_keyword(charptr->str);
  587.          index_add_demo(wrdptr->indexptr, icnptr);
  588.          charptr->indexflag = 1;
  589.          charptr = charptr->next;
  590.          }
  591.       icnptr->numkey = i;
  592.       KW_change = FALSE;
  593.       }
  594.  
  595.    if (EF_change)
  596.       {
  597.       icnptr->ok = TRUE;
  598.       tmpfptr = icnptr->addtlfiles;
  599.       /* delete all of the old files */
  600.       while (tmpfptr != NULL) 
  601.          {  
  602.          remove_file(tmpfptr->file);
  603.          tmpfptr->file = NULL;
  604.          tmpfptr = tmpfptr->next;
  605.          }
  606.       /* add all of the files from the interface */
  607.       charptr = Head_FL;
  608.       tmpfptr = icnptr->addtlfiles;
  609.       prevfptr = NULL;
  610.       while (charptr != NULL)
  611.          {
  612.          if (tmpfptr == NULL)
  613.             {
  614.             tmpfptr = (struct filelist *)malloc(sizeof(struct filelist) );
  615.             tmpfptr->next = NULL;
  616.             if (icnptr->addtlfiles == NULL)
  617.                icnptr->addtlfiles = tmpfptr;
  618.             }
  619.          tmpfptr->file = add_file(charptr->str);
  620.          if (tmpfptr->file != NULL)
  621.             icnptr->ok = tmpfptr->file->ok;
  622.  
  623.          if (prevfptr != NULL)
  624.             prevfptr->next = tmpfptr;
  625.          prevfptr = tmpfptr;
  626.          tmpfptr = tmpfptr->next;
  627.  
  628.          free(charptr->str);
  629.          prevcharptr = charptr->next;
  630.          free(charptr);
  631.          charptr = prevcharptr;
  632.          }
  633.       /* if I have fewer files now than I used to, delete the
  634.          unused storage */
  635.       if (prevfptr != NULL)
  636.           prevfptr->next = NULL;
  637.       while (tmpfptr != NULL)
  638.          {
  639.          prevfptr = tmpfptr->next;
  640.          free(tmpfptr);
  641.          tmpfptr = prevfptr;
  642.          }
  643.  
  644.       if (Head_FL == NULL)
  645.          icnptr->addtlfiles = NULL;
  646.       Head_FL = NULL;
  647.       Tail_FL = NULL;
  648.       EF_change = FALSE;
  649.       /* update ok for all instances of this demo */
  650.       fix_icon_ok(icnptr);
  651.       /* update ok for all the groups that this demo belongs to */
  652.       grplstptr = icnptr->grps;
  653.       while (grplstptr != NULL)
  654.          {
  655.          if (grplstptr->grpptr != NULL)
  656.             fix_grp_ok(grplstptr->grpptr);
  657.          grplstptr = grplstptr->next;
  658.          }
  659.       }
  660.    if (indexchange && Indexwin >= 0)
  661.       update_index_win();
  662. }
  663.  
  664. /* new_icn creates a new icon, then zeroes out most of the information
  665.  * to keep from referencing bogus values.  This fixes a bug that Ratman
  666.  * found where a bogus value in numkey was causing pointers to be 
  667.  * traversed beyond the NULL value. Fixed by Gretch.
  668.  */
  669. struct icntmpltstruct *new_icn()
  670. {
  671.    struct icntmpltstruct *newicon;
  672.    int i,j;
  673.  
  674.    newicon = (struct icntmpltstruct *) malloc(sizeof(struct icntmpltstruct));
  675.  
  676. /* now zero EVERYTHING out */
  677.    newicon->tex_image = NULL;
  678.    newicon->tex_id = 0;
  679.    newicon->tex_width = 0;
  680.    newicon->tex_height = 0;
  681.    newicon->poly = NULL;
  682.    newicon->keywords = NULL;
  683.    newicon->nameptr = NULL;
  684.    newicon->infoptr = NULL;
  685.    newicon->geofile = NULL;
  686.    newicon->imgfile = NULL;
  687.    newicon->helpfile = NULL;
  688.    newicon->addtlfiles = NULL;
  689.    newicon->nexticntmplt = NULL;
  690.    newicon->grps = NULL;
  691.    newicon->xsize = 0;
  692.  
  693.    for (i=0; i <4; i++)
  694.     {
  695.      for (j=0; j<3; j++)
  696.       {
  697.        newicon->bbox[i][j] = 0;
  698.       }
  699.     }
  700.  
  701.    newicon->numkey = 0;
  702.    newicon->numpoly = 0;
  703.    newicon->occurences = 0;
  704.    newicon->iconnum = 0;
  705.    newicon->startstring = NULL;
  706.    newicon->alt_command = NULL;
  707.  
  708.    newicon->ok = TRUE;
  709.  
  710.    return(newicon);            /* return pointer to this info */
  711. /************************************************************
  712. *
  713. * Add a demo to the book.  Add it to a group if requested.
  714. * Add it to the alphabeitcal group.
  715. *
  716. ************************************************************/
  717. void add_demo()
  718. {
  719.    struct wordlist *wrdptr;
  720.    struct charlist *charptr, *prevcharptr;
  721.    int i;
  722.    FILE *iconfp;
  723.    struct icntmpltstruct *newicon, *curicon, *previcon;
  724.    struct grptmpltstruct *tmpgrp;
  725.    IMAGE *image;
  726.    struct filelist *tmpfptr, *lastfile;
  727.    Boolean done;
  728.  
  729.  
  730.    /*if (ADName.bufpos == 0 && ADCommand.bufpos == 0)   don't add */
  731.    if (ADName.bufpos != 0 || ADCommand.bufpos != 0)/* if something's there, add */
  732.       {
  733.       if (ADName.bufpos == 0)    /* if no name is there, falsify one */
  734.          {
  735.          strcpy(ADName.buf, "No Name");
  736.          ADName.bufpos = 8;
  737.          }
  738.    lastfile = NULL;                /* reset lastfile */
  739.    newicon = new_icn();                /* get pointer to icon info */
  740.    /* assume the the numberoficons (global) hasn't been incremented yet */
  741.    if (firsticon == NULL)            /* if not set yet */
  742.       {
  743.       firsticon = newicon;            /* this IS the first icon */
  744.       lasticon = newicon;            /* and the ONLY icon! */
  745.       }
  746.    else                        /* there are other icons... */
  747.       {
  748.       previcon = NULL;                 /* we don't know which this is */
  749.       curicon = firsticon;            /* traverse icons */
  750.       while (curicon != NULL && strcmp(ADName.buf,curicon->nameptr->string)>0)
  751.          { 
  752.          previcon = curicon; 
  753.          curicon = curicon->nexticntmplt; 
  754.          }
  755.       if (curicon == NULL)
  756.          {
  757.          previcon->nexticntmplt = newicon;
  758.          lasticon = newicon;
  759.          }
  760.       else if (curicon == firsticon)
  761.          {
  762.          newicon->nexticntmplt = firsticon;
  763.          firsticon = newicon;
  764.          }
  765.       else
  766.          {
  767.          previcon->nexticntmplt = newicon;
  768.          newicon->nexticntmplt = curicon;
  769.          }
  770.       }
  771. /* redo alphabetical group */
  772.    tmpgrp = firstgroup;
  773.    done = FALSE;
  774.    while (!done && tmpgrp != NULL)
  775.       {
  776.       if (tmpgrp->nameptr == find_keyword("Master Index"))
  777.          done = TRUE;
  778.       else
  779.          tmpgrp = tmpgrp->nextgrp;
  780.       }
  781.    if (tmpgrp != NULL)
  782.       group_setup(firsticon, 0, tmpgrp);
  783.    newicon->nameptr = add_keyword(ADName.buf);
  784.    newicon->nameptr->icon = newicon;
  785.    newicon->occurences = 1;
  786.  
  787.    charptr = HeadChar;
  788.    i = 0;
  789.    while (charptr != NULL)
  790.       {
  791.       if (newicon->keywords == NULL)
  792.          {
  793.          newicon->keywords=(struct wordlist *)
  794.                                malloc(sizeof(struct wordlist));
  795.          wrdptr = newicon->keywords;
  796.          wrdptr->next = NULL;
  797.          }
  798.       else
  799.          {
  800.          wrdptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  801.          wrdptr = wrdptr->next;
  802.          wrdptr->next = NULL;
  803.          }
  804.       i++;
  805.       wrdptr->indexptr = add_keyword(charptr->str);
  806.       index_add_demo(wrdptr->indexptr, newicon);
  807.       prevcharptr = charptr->next;
  808.       if (charptr->indexflag == 0)
  809.          free(charptr->str);
  810.       free(charptr);
  811.       charptr = prevcharptr;
  812.       }
  813.    newicon->numkey = i;
  814.    HeadChar = NULL;
  815.    TailChar = NULL;
  816.  
  817.     /* need to make sure this is NULL */
  818.    tmpfptr = newicon->addtlfiles;
  819.    lastfile = NULL;
  820.    while (tmpfptr != NULL)
  821.       {  
  822.       lastfile = tmpfptr;
  823.       tmpfptr = tmpfptr->next;
  824.       }
  825.    charptr = Head_FL;
  826.    while (charptr != NULL)
  827.       {
  828.       if (charptr->indexflag == 0)
  829.          { 
  830.          tmpfptr = (struct filelist *)malloc( sizeof(struct filelist) );
  831.          tmpfptr->file = add_file(charptr->str);
  832.          if (tmpfptr->file != NULL && !tmpfptr->file->ok)
  833.             newicon->ok = FALSE;
  834.          tmpfptr->next = NULL;
  835.          free(charptr->str);
  836.          if (lastfile == NULL)
  837.             {
  838.             newicon->addtlfiles = tmpfptr;
  839.             lastfile = tmpfptr;
  840.             }
  841.          else
  842.             {
  843.             lastfile->next = tmpfptr;
  844.             lastfile = tmpfptr;
  845.             }
  846.          }
  847.       prevcharptr = charptr->next;
  848.       free(charptr);
  849.       charptr = prevcharptr;
  850.       }
  851.    Head_FL = NULL;
  852.    Tail_FL = NULL;
  853.    set_start_string( newicon , ADCommand.buf);
  854.    set_alt_command( newicon , ADAltCommand.buf);
  855.    newicon->geofile = NULL;
  856.    newicon->imgfile = NULL;
  857.    newicon->helpfile = NULL;
  858.    newicon->poly = NULL;
  859.    newicon->tex_image = NULL;
  860.    newicon->tex_width = 0;
  861.    newicon->tex_height = 0;
  862.    newicon->tex_id = -1;
  863.    if (ADHfile.bufpos > 0)
  864.       newicon->helpfile = add_file(ADHfile.buf);
  865.    if (ADIfile.bufpos > 0)
  866.       newicon->geofile = add_file(ADIfile.buf);
  867.    if (ADIfile2.bufpos > 0)
  868.       newicon->imgfile = add_file(ADIfile2.buf);
  869.    do_iconfiles(newicon);
  870.    ++numberoficons;
  871.       }
  872.    if (Indexwin >= 0)
  873.       update_index_win();
  874. }
  875.  
  876.  
  877. /************************************************************
  878. *
  879. * The rest of this .c file deals with the files
  880. * that the demos need to run.
  881. *
  882. ************************************************************/
  883. void print_icon_files(struct icntmpltstruct *icn)
  884. {
  885.    struct filelist *tmpfptr;
  886.  
  887.    tmpfptr = icn->addtlfiles;
  888.    while( tmpfptr != NULL)
  889.       {
  890.       printf(" file %s \n",tmpfptr->file->name);
  891.       tmpfptr = tmpfptr->next;
  892.       }
  893.   printf("\n");
  894. }
  895.  
  896. void print_files()
  897. {
  898.    struct filestruct *tmpptr;
  899.  
  900.    tmpptr = headfile;
  901.    while (tmpptr != NULL)
  902.       {
  903.       printf(" file %s,    occurences %d \n",tmpptr->name, tmpptr->occurences);
  904.       tmpptr = tmpptr->next;
  905.       }
  906. }
  907.  
  908. void check_files()
  909. {
  910.    struct filestruct *tmpptr, *nxtptr;
  911.    int cmp1, cmp2;
  912.  
  913.    tmpptr = headfile;
  914.    while (tmpptr != NULL)
  915.       {
  916.       cmp1 = -5; cmp2 = -5;
  917.       if (tmpptr->occurences == 0)
  918.          {
  919.          nxtptr = tmpptr->next;
  920. /*
  921.          printf(" removing file %s because occurences = 0 \n",tmpptr->name);
  922. */
  923.          remove_file(tmpptr);
  924.          tmpptr = nxtptr;
  925.          }
  926.       else if ((cmp1 = strncmp(tmpptr->name, "demos/", 6)) == 0 || (cmp2 = strncmp(tmpptr->name, "../", 3))==0)
  927.          {     /* check for demos/something or ../data/demos   */
  928.          nxtptr = tmpptr->next;
  929.          tmpptr->occurences = 0;
  930.          remove_file(tmpptr);
  931.          tmpptr = nxtptr;
  932.          }
  933.       else
  934.          tmpptr = tmpptr->next;
  935.       }
  936. }
  937.  
  938. /************************************************************
  939. *
  940. * Add a file to the file list.
  941. *
  942. ************************************************************/
  943. struct filestruct *add_file(char *newfile)
  944. {
  945.    struct filestruct *tmpptr, *insert, *curptr;
  946.    int cmp_result;
  947.    int length;
  948.    int acc_ret;
  949.  
  950.    tmpptr = NULL;
  951.    insert = NULL;
  952.    cmp_result = -1;
  953.    curptr = headfile;
  954. if (curptr != NULL)
  955.    while (curptr != NULL && (cmp_result=strcmp(newfile, curptr->name)) > 0)
  956.       {
  957.       insert = curptr;
  958.       curptr = curptr->next;
  959.       }
  960.    if (cmp_result != 0) /* the file is not in the list */
  961.       {
  962.       tmpptr = (struct filestruct *)malloc( sizeof(struct filestruct) );
  963.       length = strlen(newfile);
  964.       tmpptr->name = (char *)malloc(length +1);
  965.       tmpptr->name = strcpy(tmpptr->name,newfile);
  966.       if ((acc_ret = access(tmpptr->name, F_OK)) == 0)
  967.          tmpptr->ok = TRUE;
  968.       else
  969.          tmpptr->ok = FALSE;
  970.       tmpptr->occurences = 1;
  971.       tmpptr->written = FALSE;
  972.       tmpptr->count = 0;
  973.       tmpptr->icon = NULL;
  974.       if (headfile == NULL)
  975.          {
  976.          headfile = tmpptr;
  977.          tmpptr->next = NULL;
  978.          }
  979.       else if (insert == NULL)
  980.          {
  981.          tmpptr->next = headfile;
  982.          headfile = tmpptr;
  983.          }
  984.       else
  985.          {
  986.          insert->next = tmpptr;
  987.          tmpptr->next = curptr;
  988.          }
  989.       }
  990.    else   /* the file was in the list */
  991.       {
  992.       tmpptr = curptr;
  993.       curptr->occurences++;
  994.       }
  995.    return(tmpptr);
  996. }
  997.  
  998. /************************************************************
  999. *
  1000. * Remove a file from the file list.
  1001. *
  1002. ************************************************************/
  1003. void remove_file(struct filestruct *deadfileptr)
  1004. {
  1005.    struct filestruct *prevptr, *curptr;
  1006.    int cmp_result;
  1007.  
  1008.    if (deadfileptr != NULL)
  1009.       {
  1010.    curptr = headfile;
  1011.    prevptr = NULL;
  1012.    while (curptr != NULL && (cmp_result=strcmp(deadfileptr->name, curptr->name)) > 0)
  1013.       {
  1014.       prevptr = curptr;
  1015.       curptr = curptr->next;
  1016.       }
  1017.    if (cmp_result == 0)
  1018.       {
  1019.       if (curptr->occurences <= 1)
  1020.         {
  1021.         free(curptr->name);
  1022.         curptr->name = NULL;
  1023.         if (curptr == headfile)
  1024.            headfile = curptr->next;
  1025.         else
  1026.            prevptr->next = curptr->next;
  1027.         free(curptr);
  1028.         curptr = NULL;
  1029.         }
  1030.       else
  1031.         curptr->occurences--;
  1032.       }
  1033.       }
  1034. }
  1035.  
  1036. /************************************************************
  1037. *
  1038. * The file name pointers in the icon structure have already
  1039. * been set.  THis routine checkes that the files are present. 
  1040. * If the machine does texture mapping, the imgfile will be
  1041. * read.  If that file can not be found, or the machine does
  1042. * not do texture mapping, the geofile will be used.  If a
  1043. * geofile does not exist or has not been specified, only the
  1044. * demoname will be drawn.
  1045. *
  1046. ************************************************************/
  1047. void do_iconfiles(struct icntmpltstruct *icnptr)
  1048. {
  1049.    FILE *iconfp;
  1050.    char *fname;
  1051.    int ret;
  1052.  
  1053.    iconfp = NULL;
  1054.    if (icnptr->tex_image != NULL)
  1055.       free(icnptr->tex_image);
  1056.    if (icnptr->poly != NULL)
  1057.       free(icnptr->poly);
  1058.       icnptr->tex_image = NULL;
  1059.       icnptr->poly = NULL;
  1060.       icnptr->numpoly = 0;
  1061.       if (getgdesc(GD_TEXTURE) && icnptr->imgfile != NULL)
  1062.          {
  1063.          readicon_i( icnptr);
  1064.          icnptr->xsize = 1.0;
  1065.          icnptr->bbox[0][0] = -.1;
  1066.          icnptr->bbox[0][1] = -.1;
  1067.          icnptr->bbox[0][2] = 0.0;
  1068.          icnptr->bbox[1][0] = 1.1;
  1069.          icnptr->bbox[1][1] = -.1;
  1070.          icnptr->bbox[1][2] = 0.0;
  1071.          icnptr->bbox[2][0] = 1.1;
  1072.          icnptr->bbox[2][1] = 1.1;
  1073.          icnptr->bbox[2][2] = 0.0;
  1074.          icnptr->bbox[3][0] = -.1;
  1075.          icnptr->bbox[3][1] = 1.1;
  1076.          icnptr->bbox[3][2] = 0.0;
  1077.          }
  1078.            /* if the machine doesn't do texture mapping,
  1079.               or there's not a img file, or reading it
  1080.               doesn't work read the WorkSpace icon */
  1081.       if (icnptr->tex_image == NULL)
  1082.          {
  1083.          if (icnptr->geofile != NULL)
  1084.             {
  1085.             if (demoenv != NULL && strncmp("$DEMOS", icnptr->geofile->name, 6) == 0)
  1086.                {
  1087.                fname = (char *)malloc(demoenvlen + strlen(icnptr->geofile->name) );
  1088.                strcpy(fname, demoenv);
  1089.                strcpy(&(fname[demoenvlen]), &(icnptr->geofile->name[6]));
  1090.                }
  1091.             else if (xenv != NULL && strncmp("$XDEMOS", icnptr->geofile->name, 7) == 0)
  1092.                {
  1093.                fname = (char *)malloc(xenvlen + strlen(icnptr->geofile->name) );
  1094.                strcpy(fname, xenv);
  1095.                strcpy(&(fname[xenvlen]), &(icnptr->geofile->name[7]));
  1096.                }
  1097.             else if (sbenv != NULL && strncmp("$SBIN", icnptr->geofile->name, 5) == 0)
  1098.                {
  1099.                fname = (char *)malloc(sbenvlen + strlen(icnptr->geofile->name) );
  1100.                strcpy(fname, sbenv);
  1101.                strcpy(&(fname[sbenvlen]), &(icnptr->geofile->name[5]));
  1102.                }
  1103.             else
  1104.                {
  1105.                fname = (char *)malloc(1 + strlen(icnptr->geofile->name) );
  1106.                strcpy(fname, icnptr->geofile->name);
  1107.                }
  1108.             if ( (iconfp = fopen(fname, "r") ) == NULL)
  1109.                {
  1110.                sprintf(msgstring, "\nDemo %s\nCould not open iconfile:\n%s",icnptr->nameptr->string, icnptr->geofile->name);
  1111.                popup_Message();
  1112.                handleMessageEvents();
  1113.                icnptr->numpoly = 0;
  1114.                }
  1115.            else
  1116.                {
  1117.                icnptr->numpoly = countpolys(iconfp);
  1118.                icnptr->poly = (struct polylist *)
  1119.                    malloc((icnptr->numpoly)*sizeof(struct polylist) );
  1120.                lastvertex =readicon_g(iconfp,icnptr,lastvertex);
  1121.                }
  1122.             if (iconfp != NULL)
  1123.                {
  1124.                ret = fclose(iconfp);
  1125.                }
  1126.             free(fname);
  1127.             }
  1128.          }
  1129. }
  1130.  
  1131.  
  1132.